{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 函数练习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import torch "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-10.,  -5.,   0.,   5.,  10.])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.linspace(-10, 10, 5)          # 等差数列采样\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = np.arange(9).reshape(3,3)\n",
    "b = np.arange(3)\n",
    "c = np.add(a,b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "?np.add.at"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. numpy.add.at"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2, 4, 3, 4])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1, 2, 3, 4])\n",
    "b = np.array([1, 2])\n",
    "np.add.at(a, [0, 1], b)   # 在第0和1位置叠加b中对应的元素\n",
    "a                         # 在a自身上加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2, 3, 5, 4])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1, 2, 3, 4])\n",
    "np.add.at(a, [0, 1, 2, 2], 1)     # 在第0,1,2,2位置分别加1，第2个位置加了两次1\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1, -2,  3,  4])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1, 2, 3, 4])\n",
    "np.negative.at(a, [0, 1])       # 第0和1位置取负\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1 2]\n",
      " [3 4 5]\n",
      " [6 7 8]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[2, 3, 4],\n",
       "       [4, 5, 6],\n",
       "       [6, 7, 8]])"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.arange(9).reshape(3,3)\n",
    "print(a)\n",
    "b = np.array([1,1,1])\n",
    "np.add.at(a,[0,1,0],b)\n",
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.numpy数组与列表切片索引不会溢出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8]\n",
      "[3 4 5 6 7 8]\n"
     ]
    }
   ],
   "source": [
    "a = np.arange(9)\n",
    "print(a)\n",
    "print(a[3:20])           # 即使end=20超过索引范围，直接返回已有数据，不会报错\n",
    "b = a[20:30]             # 如果切片索引无效，返回空数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 4, 5, 6]\n",
      "[]\n"
     ]
    }
   ],
   "source": [
    "l = [1,2,3,4,5,6]\n",
    "print(l[2:20])                  # 列表也不会出现切片索引溢出问题\n",
    "print(l[20:30])                 # 如果切片索引无效，返回空列表"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. array[None]在增加一个一维的第0维度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3, 3)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[0, 1, 2],\n",
       "       [3, 4, 5],\n",
       "       [6, 7, 8]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.arange(9).reshape((3,3))\n",
    "print(a.shape)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 3, 3)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[[0, 1, 2],\n",
       "        [3, 4, 5],\n",
       "        [6, 7, 8]]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(a[None].shape)\n",
    "a[None]                     # 在最开始增加了一个维度，该维度为1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.torch定义变量类型 type_as方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.DoubleTensor tensor([1., 2., 3.], dtype=torch.float64)\n",
      "torch.FloatTensor tensor([1.1000, 2.2000])\n"
     ]
    }
   ],
   "source": [
    "tensor1 = torch.tensor([1,2,3], dtype=torch.float64)\n",
    "print(tensor1.type(), tensor1)\n",
    "tensor2 = torch.tensor([1.1,2.2]).type_as(tensor1)   # 默认float，但type_as会使用tensor1相同的类型\n",
    "print(tensor2.type(), tensor2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-1,  2,  3],\n",
      "        [-2,  5,  0]]) torch.Size([2, 3])\n",
      "tensor([[1, 2, 3],\n",
      "        [2, 5, 0]])\n",
      "(tensor([3, 5]), tensor([2, 1]))\n"
     ]
    }
   ],
   "source": [
    "tensor1 = torch.tensor([[-1,2,3],[-2,5,0]])\n",
    "print(tensor1, tensor1.shape)\n",
    "print(torch.abs(tensor1))\n",
    "print(torch.max(tensor1, dim=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.PyTorch中matmul多维数组的矩阵乘积(numpy也有该函数)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([2, 3, 3])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[[1.0857, 0.9276, 0.9489],\n",
       "         [1.1151, 0.8544, 0.6473],\n",
       "         [0.6746, 0.4827, 0.3723]],\n",
       "\n",
       "        [[0.6092, 0.7565, 0.8553],\n",
       "         [0.6252, 1.0438, 0.7623],\n",
       "         [1.1651, 1.6631, 1.9378]]])"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.rand((2,3,4))         # (N,H,W) \n",
    "b = torch.rand((2,4,3))         # (N,W,H)\n",
    "c = a.matmul(b)                 # matmul多维的矩阵乘积 批量矩阵乘积 (N,H,H) \n",
    "print(c.shape)\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([1, 2, 3, 3])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[[[1.1186, 0.6705, 0.9549],\n",
       "          [1.3065, 0.5903, 0.9391],\n",
       "          [1.2467, 0.5384, 0.9302]],\n",
       "\n",
       "         [[1.3541, 0.9563, 1.2770],\n",
       "          [1.9333, 0.8833, 1.5378],\n",
       "          [1.1064, 0.3854, 0.8678]]]])"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.rand((1,2,3,4))            # (N,H,W) \n",
    "b = torch.rand((1,2,3,4))            # (N,W,H)\n",
    "c = a.matmul(b.permute(0,1,3,2))     # permute交换坐标轴，可同时换多个 (N,H,H) \n",
    "print(c.shape)\n",
    "c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.numpy ceil向上取整"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-1., -2., -0.,  0.,  2.,  4.])"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([-1.2,-2.3,-0.5,0,1.2,3.4])\n",
    "np.ceil(a)               # 向上取整"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 4 5 6 7 8 9 "
     ]
    }
   ],
   "source": [
    "it = iter(range(1,10))          # 创建一个迭代器\n",
    "for i in it:\n",
    "    print(i, end=' ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = torch.tensor([1]*5)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2., 2., 2.],\n",
       "        [2., 2., 2.]])"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.ones((2,3) )\n",
    "b = torch.ones((2,3))*2\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(12.)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.sum(a.mul(b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[4., 4., 4.],\n",
       "        [4., 4., 4.]])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.1903, 1.1325, 0.8145],\n",
       "        [0.4886, 0.8139, 0.5970]])"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = torch.rand((2,4))\n",
    "b = torch.rand((4,3))\n",
    "a.mm(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-7.3873, -7.3518, -7.2636, -7.9005],\n",
      "        [-7.6141, -7.9448, -7.5144, -7.8211]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[-7.3873, -7.6141],\n",
       "        [-7.3518, -7.9448],\n",
       "        [-7.2636, -7.5144],\n",
       "        [-7.9005, -7.8211]])"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(a) \n",
    "a.t()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-8.3873, -8.3518, -8.2636, -8.9005],\n",
       "        [-8.6141, -8.9448, -8.5144, -8.8211]])"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.sub_(1)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[[0.2570, 0.5183, 0.5469, 0.4554],\n",
       "          [0.2139, 0.8243, 0.4869, 0.1604],\n",
       "          [0.4762, 0.7017, 0.5138, 0.0362]],\n",
       "\n",
       "         [[0.4944, 0.2622, 0.7662, 0.7043],\n",
       "          [0.3446, 0.9476, 0.4081, 0.9453],\n",
       "          [0.0331, 0.5100, 0.5556, 0.3637]]]])"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = a.clone()\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "?nn.LeakyReLU"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
